package com.newidea.facillty.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.newidea.facillty.entity.HeatFacility;
import com.newidea.facillty.utils.ModbusUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;


@Service
@Slf4j
public class DatunService {

    /**
     * modbusTcp地址
     */
    @Value("${collect.modbus.tcpIp}")
    private String tcpIp;
    /**
     * modbusTcp端口
     */
    @Value("${collect.modbus.tcpPort}")
    private int tcpPort;

    public JSONObject collect() {
        try {
            // 创建ModbusMasterTCP连接
            ModbusMaster master = ModbusUtil.createModbusMasterTCP(tcpIp, tcpPort);
            // 从ModbusMaster中获取设备状态并新增
            List<HeatFacility> states = insertStates(master);
            // 从ModbusMaster中获取设备值并新增
            List<HeatFacility> values = insertValues(master);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("states", states);
            jsonObject.put("values", values);
            // 断开连接
            master.disconnect();

            return jsonObject;
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 从ModbusMaster中获取设备状态并新增
     *
     * @param master ModbusMasterTCP
     */
    private List<HeatFacility> insertStates(ModbusMaster master)
        throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
        // 读取json配置的状态
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("facility/datun/facilityState.json");
        if (in == null) {
            throw new RuntimeException("未能读取到配置文件facilityState.json");
        }
        JSONArray facilityStates = JSONUtil.parseArray(IoUtil.read(in, StandardCharsets.UTF_8));
        log.info("成功读取配置文件facilityState.json");
        List<HeatFacility> heatFacilityList = facilityStates.toList(HeatFacility.class);

        int slaveId = 1;
        // 读取开始地址
        int offset = 0;
        // 读取数量
        int quantity = heatFacilityList.size();

        // 读取线圈内容，返回数组的长度为8的倍数
        boolean[] values = master.readDiscreteInputs(slaveId, offset, quantity);

        // 当前时间
        String now = DateUtil.now();

        for (int i = 0; i < quantity; i++) {
            HeatFacility heatFacility = heatFacilityList.get(i);
            heatFacility.setCreateTime(now);
            // true设置1，false设置0
            heatFacility.setValue(values[i] ? "1" : "0");
        }
        log.info("采集ModbusTcp设备状态：{}条。", quantity);
        return heatFacilityList;
    }

    /**
     * 从ModbusMaster中获取设备值并新增
     *
     * @param master ModbusMasterTCP
     */
    private List<HeatFacility> insertValues(ModbusMaster master)
        throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("facility/datun/facilityValue.json");
        if (in == null) {
            throw new RuntimeException("未能读取到配置文件facilityValue.json");
        }

        JSONArray facilityValue = JSONUtil.parseArray(IoUtil.read(in, StandardCharsets.UTF_8));
        log.info("成功读取配置文件facilityValue.json");
        List<HeatFacility> heatFacilityList = facilityValue.toList(HeatFacility.class);

        int slaveId = 1;
        // 读取开始地址
        int offset = 0;
        // 读取数量
        int quantity = 105;
        // 读取寄存器值
        int[] values = master.readHoldingRegisters(slaveId, offset, quantity);
        // 当前时间
        String now = DateUtil.now();

        for (int i = 0, v = 0; i < heatFacilityList.size(); i++, v += 2) {
            HeatFacility heatFacility = heatFacilityList.get(i);
            heatFacility.setCreateTime(now);
            int value = values[v];
            if (v + 1 < quantity) {
                int value1 = values[v + 1];
                heatFacility.setValue(value + "," + value1);
            } else {
                heatFacility.setValue(String.valueOf(value));
            }
        }
        log.info("采集ModbusTcp设备值：{}条。", heatFacilityList.size());
        return heatFacilityList;
    }

}
